<?php
/**
 * konakona php class
 * @author konakona
 * @date 2009-9-18
 * @version 1.0.2
 */
class k {
    public static $DEBUG = false;
    public static $ROOT = null;
    public static $DS = null;
    //COUNTER
    public static $fileReadCounter = 0;
    public static $fileWriterCounter = 0;

    //GLOBAL CONFIG
    public static $config = array();
    //IMPORTED
    public static $import = array();
    /**
     * 初始化run
	 * k::run();
     */
    public static function run($arrConf = FALSE) {
	session_start();
        if(empty(self::$ROOT))
            self::$ROOT = substr(__FILE__, 0, -12);// 获取当前路径
        if(empty(self::$DS))
            self::$DS = DIRECTORY_SEPARATOR;// 获取win或linux下的文件分隔符 // \ /
		if(empty($arrConf)){
			self::loadConfig();//加载配置变量
			//self::loadConfig('config.php');//外部加载方式
        }else if(is_array($arrConf))
			self::$config = $arrConf;
		else
			self::loadConfig($arrConf);
		//config file not exists退出
        if(empty(self::$config)) { return false; }
        //if config exists 進行設置
        if( isset( self::$config['ERROR_REPORTING'] ) ) { error_reporting(self::$config['ERROR_REPORTING']); }
        if(isset(self::$config['TIMEZONE'])) { date_default_timezone_set(self::$config['TIMEZONE']); }
		if(isset(self::$config['DEBUG'])) {self::$DEBUG = self::$config['DEBUG'];}
        //set_error_handler('k::errorCallback');
        //如果找不到类就执行这个方法（自动寻找文件夹下的类）
        spl_autoload_register('k::autoLoad');
	  set_magic_quotes_runtime(0);
        return true;
    }
    /**
     * 加载配置
     * @param string $filePath 配置文件的路径
     */
    private static function loadConfig($filePath = '') {
		if(empty($filePath)){$filePath = self::$ROOT.self::$DS.'config.php';}
        if(empty(self::$config)) { self::$config = include $filePath; }
    }
    /**
     * 类库自动加载函数
     * @param string $className 类名
     */
    public static function autoLoad($className){
        if(file_exists(self::$ROOT.'core'.self::$DS.$className.'.php')){
            include self::$ROOT.'core'.self::$DS.$className.'.php';
            return;
        }
        if(file_exists(self::$ROOT.'controller'.self::$DS.$className.'.php')){
            include self::$ROOT.'controller'.self::$DS.$className.'.php';
            return;
        }
    }
    /**
     * 加载
     * @param string @package 包名 k::import( 'plugin.Smarty' );
     */
    public static function import($package) {
        $arrTemp = explode('.',$package);
        include(k::$ROOT.implode(k::$DS,$arrTemp).'.php');
    }

    /**
     * 为变量或者数组添加转义
     * @param string $value - 字符串或者数组
     * @return array
     */
    public static function addslashes($value) {
        return $value = is_array($value) ? array_map('k::addslashes', $value) : addslashes($value);
    }
    /**
     * 为变量或者数组取消转义
     * @param string $value - 字符串或者数组
     * @return array
     */
    public static function stripslashes($value) {
        return $value = is_array($value) ? array_map('k::stripslashes', $value) : addslashes($value);
    }

    /**
     * 将特殊字符转成 HTML 格式。
     * @param string $value - 字符串或者数组
     * @return array
     */
    public static function htmlspecialchars($value) {
        return is_array($value) ? array_map('k::htmlspecialchars', $value) :
		preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',
		str_replace(array('&', '"', '<', '>'), array('&amp;', '&quot;', '&lt;', '&gt;'), $value));
    }
    /**
     * 将字符串中的标签去除
     * @param string $value - 字符串或者数组
     * @return array
     */
	public static function striptags($value){
        return $value = is_array($value) ? array_map('k::striptags', $value) : strip_tags($value);
	}
    /**
     * 消除字符形式SQL注入
     * @param $rmix mixed
     **/
    public static function escapeSQL(&$rmix){
        if(!get_magic_quotes_gpc()) { $rmix = self::addslashes($rmix); }return $rmix;
    }
    /**
     * 取消SQL转义
     * @param $rmix mixed
     **/
    public static function unescapeSQL(&$rmix){
        if(get_magic_quotes_gpc()) { $rmix = self::stripslashes($rmix); }return $rmix;
    }
    /**
     * 读取文件
     * @param string $file 文件路径
     * @param bool $exit 当无法读取的时候是否中断,默认false
     * @param string $mode 模式,默认'rb'
     */
    public static function read($file,$mode = 'rb',$exit = false) {
        	if(!@$fp = @fopen($file, $mode)) {
				self::writeLog('cound not read file:'.$file,'k::read');
               if($exit) { self::halt('cound not read file:'.$file); } else { return false; }
           } else {
               $fileSize = filesize($file);
               ($fileSize ==0)&&($fileSize = 1);
               @$data = fread($fp,$fileSize);
        		fclose($fp);
                self::$fileReadCounter++;
                return $data;
           }
    }
    /**
     * 写入文件
     * @param string $file 文件路径
     * @param string $content 内容
     * @param bool $exit 是否中断,默认false
     * @param string $mode 模式,默认'w'
     */
    public static function write($file,$content='',$mode='w',$exit=false) {
        if(!@$fp = @fopen($file, $mode)) {
			self::writeLog('cound not write file:'.$file,'k::write');
		    if($exit) { self::halt('cound not write file:'.$file); } else { return false;}
        } else {
            @flock($fp, 2);
		    @fwrite($fp, $content);
		    @fclose($fp);
            self::$fileWriterCounter++;
            return true;
        }
    }
    /**
     * 中断
     * @param string $msg 消息
     */
    public static function halt($msg = 'unknow') {
        exit('<div style="border:solid #CCC 1px;padding:5px;color:red;font-family:verdana;
		font-size:12px;"><span style="color:#444">Error Message : </span>'.$msg.'</div>');
    }
    /**
     * 禁止客户端缓存
     */
    public static function noClientCache(){
        header("Cache-Control: no-cache, must-revalidate");
    }
    /**
     * 设置页面编码
     * @param string $encoding 编码
     */
    public static function setEncoding($encoding = false){
        $encoding = $encoding ? $encoding : self::$config['CHARSET'];
        header("Content-Type: text/html; charset={$encoding}");
    }
    /**
     * 获取IP
     */
    public static function getip() {
        if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $onlineip = getenv('HTTP_CLIENT_IP');
        } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $onlineip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $onlineip = getenv('REMOTE_ADDR');
        } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $onlineip = $_SERVER['REMOTE_ADDR'];
        }
        preg_match('/[\d\.]{7,15}/', $onlineip, $onlineipmatches);
        $onlineip = $onlineipmatches[0] ? $onlineipmatches[0] : 'unknown';
        unset($onlineipmatches);
        return $onlineip;
    }

    /**
     * 设置HTTP状态码
     * @param int $code HTTP状态码
     * @param bool $template 是否显示模板,默认true
     */
    public static function httpstatus($code,$template=true){
        $http = array (
            100 => "HTTP/1.1 100 Continue",
            101 => "HTTP/1.1 101 Switching Protocols",
            200 => "HTTP/1.1 200 OK",
            201 => "HTTP/1.1 201 Created",
            202 => "HTTP/1.1 202 Accepted",
            203 => "HTTP/1.1 203 Non-Authoritative Information",
            204 => "HTTP/1.1 204 No Content",
            205 => "HTTP/1.1 205 Reset Content",
            206 => "HTTP/1.1 206 Partial Content",
            300 => "HTTP/1.1 300 Multiple Choices",
            301 => "HTTP/1.1 301 Moved Permanently",
            302 => "HTTP/1.1 302 Found",
            303 => "HTTP/1.1 303 See Other",
            304 => "HTTP/1.1 304 Not Modified",
            305 => "HTTP/1.1 305 Use Proxy",
            307 => "HTTP/1.1 307 Temporary Redirect",
            400 => "HTTP/1.1 400 Bad Request",
            401 => "HTTP/1.1 401 Unauthorized",
            402 => "HTTP/1.1 402 Payment Required",
            403 => "HTTP/1.1 403 Forbidden",
            404 => "HTTP/1.1 404 Not Found",
            405 => "HTTP/1.1 405 Method Not Allowed",
            406 => "HTTP/1.1 406 Not Acceptable",
            407 => "HTTP/1.1 407 Proxy Authentication Required",
            408 => "HTTP/1.1 408 Request Time-out",
            409 => "HTTP/1.1 409 Conflict",
            410 => "HTTP/1.1 410 Gone",
            411 => "HTTP/1.1 411 Length Required",
            412 => "HTTP/1.1 412 Precondition Failed",
            413 => "HTTP/1.1 413 Request Entity Too Large",
            414 => "HTTP/1.1 414 Request-URI Too Large",
            415 => "HTTP/1.1 415 Unsupported Media Type",
            416 => "HTTP/1.1 416 Requested range not satisfiable",
            417 => "HTTP/1.1 417 Expectation Failed",
            500 => "HTTP/1.1 500 Internal Server Error",
            501 => "HTTP/1.1 501 Not Implemented",
            502 => "HTTP/1.1 502 Bad Gateway",
            503 => "HTTP/1.1 503 Service Unavailable",
            504 => "HTTP/1.1 504 Gateway Time-out"
        );
        header($http[$code]);
    }
    /**
     * 错误处理回调函数
     *
     * @param $errNo
     * @param $errStr
     * @param $errFile
     * @param $errLine
     */
    public static function errorCallback($errNo,$errStr,$errFile,$errLine){
        if(self::$DEBUG) {
			self::halt('<BR />SERVER 500. <BR />NO:'.
			$errNo.'<BR />'.$errStr.'<BR />file:'.
			$errFile.'<BR />line:'.$errLine);
		} else {
			self::writeLog($errNo.$errStr.$errFile.$errLine,'error');
			self::httpstatus(500);
		}
    }
	/**
	 * 日志记录函数
	 *
	 * @param string $content
	 * @param string $sender
	 */
	public static function writeLog($content = 'undefined',$sender = 'unknow'){
		$logPath = self::$ROOT.self::$config['LOG_PATH'];
		if(!file_exists($logPath)) {
			self::import('helper.tool');
			if(!class_exists('tool'))
				return FALSE;
			tool::createDirectory($logPath);
		}
		self::write($logPath.self::$DS.date('Y-m-d').'.log','msg:'.$content."\r\ntime:".date('Y-m-d H:i:s').' sender:'.$sender."\r\n",'a+');
	}
	/**
	 * 系统提示
	 *
	 * @param string $messages
	 * @param string $pageurl
	 */
	public static function message($messages,$pageurl='javascript:history.back();'){
        echo '<html>
        <head>
        <meta content="text/html; charset=gb2312" http-equiv="Content-Type">
        <title>System Message</title>
        <style type="text/css">
        *{margin:0;padding:0px}
        body{background:#fff;color:#333;font:12px Verdana, Tahoma, sans-serif;text-align:center;margin:0 auto;}
        a{text-decoration:none;color:#29458C}
        a:hover{text-decoration:underline;color:#f90}
        #msg{border:1px solid #c5d7ef;text-align:left;margin:10% auto; width:50%}
        #msgtitle{padding:5px 10px;background:#f0f6fb;border-bottom:1px #c5d7ef solid}
        #msgtitle h1{font-size:14px;font-weight:bold;padding-left:10px;border-left:3px solid #acb4be;color:#1f3a87}
        #msgcontent {padding:20px 50px;}
        #msgcontent li{display:block;padding:5px;list-style:none;}
        #msgcontent p{text-align:center;margin-top:10px;padding:0}
        </style>
        </head>
        <body>
        <div id="msg">
            <div id="msgtitle">
                <h1>Web System Message</h1>
            </div>
            <div id="msgcontent">
                ',$messages,'
                <p><a href="',$pageurl,'">>>>Please wait 5 sec or Click here</a></p>
            </div>
        </div>
        <meta http-equiv="refresh" content="5;URL=',$pageurl,'">
        </body>
        </html>';
        exit();
    }
	/**
	 * 生成验证码并存储到cookie中
	 * @return img
	 */
	public static function verificationCode() {
		$seccode = rand(100000, 999999);
		//$this->setcookie('uc_secc', $this->authcode($seccode."\t".$this->time, 'ENCODE'));
		@header("Expires: -1");
		@header("Cache-Control: no-store, private, post-check=0, pre-check=0, max-age=0", FALSE);
		@header("Pragma: no-cache");
		self::import('plugin.seccode');
		$code = new seccode();
		$code->code = $seccode;
		$code->type = 0;
		$code->width = 70;
		$code->height = 21;
		$code->background = 0;
		$code->adulterate = 1;
		$code->ttf = 1;
		$code->angle = 0;
		$code->color = 1;
		$code->size = 0;
		$code->shadow = 1;
		$code->animator = 0;
		//$code->fontpath = UC_ROOT.'images/fonts/';
		//$code->datapath = UC_ROOT.'images/';
		$code->includepath = '';
		$code->display();
	}
    /**
     * 将超长数据以...替代　适用于utf8
     * @param string $string
     * @param int $length
     * @param string $dot
     * @return string
     */
    public static function cutstr($string,$length,$dot = '...'){
		@extract($string);
        if(strlen($string) <= $length){
            return $string;
        }
		
        $string = str_replace(array('&amp;','&quot;','&lt;','&gt;'), array('&','"','<','>'), $string);
        $strcut = '';
        $n = $tn = $noc = 0;
        while($n < strlen($string)){
            $t = ord($string[$n]);
            if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)){
                $tn = 1; $n++; $noc++;
            }elseif(194 <= $t && $t <= 223){
                $tn = 2; $n += 2; $noc += 2;
            }elseif(224 <= $t && $t < 239) {
                $tn = 3; $n += 3; $noc += 2;
            }elseif(240 <= $t && $t <= 247){
                $tn = 4; $n += 4; $noc += 2;
            }elseif(248 <= $t && $t <= 251){
                $tn = 5; $n += 5; $noc += 2;
            }elseif($t == 252 || $t == 253){
                $tn = 6; $n += 6; $noc += 2;
            }else{
                $n++;
            }
            if($noc >= $length){
                break;
            }
        }
        if($noc > $length){
            $n -= $tn;
        }
        $strcut = substr($string, 0, $n);
        $strcut = str_replace(array('&','"','<','>'), array('&amp;','&quot;','&lt;','&gt;'), $strcut);
        return $strcut.$dot;
    }
    /**
     * 计算UTF-8长度
     *
     * @param string $str
     * @return int
     */
    public static function strlen_utf8($str){
        $i = 0;
        $count = 0;
        $len = strlen ($str);
        while ($i < $len){
            $chr = ord ($str[$i]);
            $count++;
            $i++;
            if($i >= $len) break;
            if($chr & 0x80) {
                $chr <<= 1;
            while ($chr & 0x80) {
                $i++;
                $chr <<= 1;
                }
            }
        }
        return $count;
    }
    /**
     * 生成form随机
     */
	public static function formhash(){
		$mtime = explode(' ', microtime());
		return substr(md5(substr($mtime[1], 0, -7).self::getip()), 8, 8);
	}
	/**
     * 检测邮箱格式合法性
     *
     * @param string $email
     * @return bool
     */
	public static function check_email($email){
		if(preg_match("/([a-z0-9]*[-_\.]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[\.][a-z]{2,3}([\.][a-z]{2})?/i",$email)){
			return true;
		}else{
			return false;
		}
	}
}